// NamedPipe.cpp: implementation of the NamedPipe class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "NamedPipe.h"
#include <exception>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

NamedPipe::NamedPipe()
{

}

NamedPipe::NamedPipe( HANDLE hPipe, LPCSTR lpName )
{
	m_hPipe = hPipe;
	memset((LPVOID)&this->szName, 0x0, 256 * sizeof(CHAR));
	strcpy(szName, lpName);
}

NamedPipe::~NamedPipe()
{
	DisConnect();
	CloseHandle(m_hPipe);
}

NamedPipe * NamedPipe::CreateServerAndConnect( LPCSTR lpName, NamedPipeServerParams params )
{
	NamedPipe * lpNamedPipe = NamedPipe::CreateServer(lpName, params);
	lpNamedPipe->Connect();
	return lpNamedPipe;
}

NamedPipe * NamedPipe::CreateServer( LPCSTR lpName, NamedPipeServerParams params )
{
	HANDLE hPipe = INVALID_HANDLE_VALUE;
	hPipe = CreateNamedPipe(lpName, params.dwOpenMode, params.dwPipeMode, params.nMaxInstance, params.nOutBufferSize, params.nInBufferSize, params.nDefaultTimeOut, params.lpSecurityAttributes);
	if (hPipe == INVALID_HANDLE_VALUE)
	{
		throw new exception("CreateNamedPipe Fail");
	}
	NamedPipe * lpNamedPipe = new NamedPipe(hPipe, lpName);
	return lpNamedPipe;
}

NamedPipe * NamedPipe::ClientFromName( LPCSTR lpName )
{
	if (!WaitNamedPipe(lpName, NMPWAIT_USE_DEFAULT_WAIT))
	{
		OutputDebugString("WaitNamedPipe TimeOut");
		throw new exception("WaitNamedPipe TimeOut");
	}
	HANDLE hPipe = INVALID_HANDLE_VALUE;
	hPipe = CreateFile(lpName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hPipe == INVALID_HANDLE_VALUE)
	{
		throw new exception("OpenPipe fail");
	}
	return new NamedPipe(hPipe, lpName);
}

void NamedPipe::Connect()
{
	if(!ConnectNamedPipe(this->m_hPipe, NULL))
	{
		throw new exception("ConnectNamedPipe Fail");
	}
}

void NamedPipe::DisConnect()
{
	DisconnectNamedPipe(m_hPipe);
}

DefaultNamedPipeServerParams::DefaultNamedPipeServerParams()
{
	this->dwOpenMode = PIPE_ACCESS_DUPLEX;
	this->dwPipeMode = PIPE_TYPE_BYTE;
	this->nMaxInstance = 1;
	this->nInBufferSize = 1 * 1024 * 1024;
	this->nOutBufferSize = 1 * 1024 * 1024;
	this->nDefaultTimeOut = NMPWAIT_WAIT_FOREVER;
	this->lpSecurityAttributes = NULL;
}

SqlDebuggerNamedPipeServerParams::SqlDebuggerNamedPipeServerParams()
{
	
}

Pipe::Pipe()
{
	
}

void Pipe::SyncRead( LPVOID lpBuff, DWORD dwLength )
{
	DWORD dwNumberOfBytesRead = 0;
	if(!ReadFile(m_hPipe, lpBuff, dwLength, &dwNumberOfBytesRead, NULL) || dwNumberOfBytesRead != dwLength)
	{
		OutputDebugString("NamedPipe ReadFile Error");
	}
}

void Pipe::SyncWrite( LPVOID lpBuff, DWORD dwLength )
{
	DWORD dwNumberOfBytesWritten = 0;
	if(!WriteFile(m_hPipe, lpBuff, dwLength, &dwNumberOfBytesWritten, NULL) || dwNumberOfBytesWritten != dwLength)
	{
		OutputDebugString("NamedPipe WriteFile Error");
	}
}
